import { useState, useEffect, useRef } from "react";
import { Button, message, Upload } from "antd";
import type { RcFile, UploadFile, UploadProps } from "antd/es/upload/interface";
import { dataURLtoFile } from "./utils";
import "./App.less";

function App() {
  const [result, setResult] = useState<string>("");
  const [loading, setLoading] = useState<boolean>(false);
  const [picMode, setPicMode] = useState<boolean>(false);
  const [fileList, setFileList] = useState<UploadFile[]>([]);

  const VideoRef = useRef(null);

  useEffect(() => {
    navigator.mediaDevices
      .getUserMedia({ video: true })
      .then(function (stream) {
        console.log(VideoRef, stream);
        const video = document.querySelector("#video") as HTMLVideoElement;
        video.srcObject = stream;
        video.onloadedmetadata = function (e) {
          video.play();
        };
      })
      .catch(function (err) {
        console.warn(err);
      });
  }, [picMode]);

  const main = async () => {
    const canvas = document.createElement("canvas") as HTMLCanvasElement;
    const video = document.querySelector("#video")! as HTMLVideoElement;
    setLoading(true);
    video.pause();

    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    canvas
      .getContext("2d")
      ?.drawImage(video, 0, 0, canvas.width, canvas.height);
    const src = canvas.toDataURL("image/png");
    const file = dataURLtoFile(src, "1.png");

    await sendFile(file);

    setLoading(false);
    video.play();
  };

  const picMain = async () => {
    if (fileList.length === 1) {
      setLoading(true);
      const file = dataURLtoFile(fileList[0].thumbUrl!, "1.png");
      await sendFile(file);
      setLoading(false);
    } else {
      message.error("请上传图片");
    }
  };

  const toggleMode = () => {
    setResult("");
    setLoading(false);
    setPicMode(!picMode);
  };

  const sendFile = async (file: File) => {
    const formData = new FormData();
    formData.append("image", file);

    await fetch("http://127.0.0.1:8888/img", {
      method: "POST",
      mode: "cors",
      body: formData,
    })
      .then((data) => data.json())
      .then((res) => {
        console.log(res.result);
        setResult(res.result);
      })
      .catch(() => {
        message.error("请检查服务器或网络是否连接");
      });
  };

  const onChange: UploadProps["onChange"] = ({ fileList: newFileList }) => {
    setFileList(newFileList);
  };

  const onPreview = async (file: UploadFile) => {
    let src = file.url as string;
    if (!src) {
      src = await new Promise((resolve) => {
        const reader = new FileReader();
        reader.readAsDataURL(file.originFileObj as RcFile);
        reader.onload = () => resolve(reader.result as string);
      });
    }
    const image = new Image();
    image.src = src;
    const imgWindow = window.open(src);
    imgWindow?.document.write(image.outerHTML);
  };

  return (
    <div className="app">
      <header>
        <h1>蔬果识别系统</h1>
        <p>Vegetable and fruit recognition system</p>
        <Button type="primary" className="toggleMode" onClick={toggleMode}>
          切换为{picMode ? "视频" : "图片"}模式
        </Button>
      </header>
      <main>
        {picMode ? (
          <div className="dragSpace">
            <Upload
              listType="picture-card"
              fileList={fileList}
              onChange={onChange}
              onPreview={onPreview}
              style={{
                width: "70vw",
              }}
            >
              {fileList.length === 0 && "+ Upload"}
            </Upload>
          </div>
        ) : (
          <video id="video" ref={VideoRef}></video>
        )}
      </main>
      <footer>
        <div className="result">
          <span>识别结果: </span>
          {!loading && <span className="name">{result}</span>}
        </div>
        <Button
          type="primary"
          size="large"
          onClick={picMode ? picMain : main}
          loading={loading}
        >
          {loading ? `识别中` : `进行识别`}
        </Button>
      </footer>
    </div>
  );
}

export default App;
